import logging
from flask_babel import _
from controllers.errors.online_mall.prop_errors import HPropNotFoundError, HPropParamError
from core.entities.account_role import AccountWrap
from extensions.ext_database import db
from models.online_mall.prod_other import (
    MProdProperty,
    MProdAttrValue,
)
from werkzeug.exceptions import InternalServerError
from services.errors.account import NotLoginError

class ProdPropService:
    # @staticmethod
    # def get_prop_max_value_id(prop_id)->int:
    #     max_value = db.session.query(MProdAttrValue).filter(MProdAttrValue.prop_id==prop_id).order_by(MProdAttrValue.id.desc()).first
    @staticmethod
    def create_prop(account:AccountWrap,args:dict)->MProdProperty:
        if not account or not isinstance(account,AccountWrap):
            raise NotLoginError()
        shop_id = args.get('shop_id')
        if not shop_id:
            raise HPropParamError(_("Shop ID is required"))
        if 'is_sale_rule' not in args or args['is_sale_rule'] is None:
            raise HPropParamError(_("is_sale_rule is required"))
        if 'name' not in args or not args['name']:
            raise HPropParamError(_("Name is required"))
        if 'prop_values' not in args or not args['prop_values']:
            raise HPropParamError(_("Prop values is required"))
        try:
            prop = MProdProperty(
                shop_id = args["shop_id"], # type:ignore
                is_sale_rule = args.get('is_sale_rule'),# type:ignore
                name = args.get('name'),# type:ignore
                created_by = account.id# type:ignore
            )
            db.session.add(prop)
            db.session.commit()
            for i in args['prop_values']:
                prop_value = MProdAttrValue(
                    prop_id = prop.id, # type:ignore
                    val = i, # type:ignore
                    created_by = account.id,  # type:ignore
                )
                db.session.add(prop_value)
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            raise InternalServerError(str(e))

    @staticmethod
    def update_prop(account:AccountWrap,args:dict)->MProdProperty:
        if not account or not isinstance(account,AccountWrap):
            raise NotLoginError()
        prop_id = args.get('id')
        if not prop_id:
            raise HPropParamError(_("Product  ID is required"))
        prop = db.session.get(MProdProperty,prop_id)
        if not prop:
            raise HPropNotFoundError(prop_id)
        
        shop_id = args.get('shop_id')
        if not shop_id:
            raise HPropParamError(_("Shop ID is required"))
        if 'is_sale_rule' not in args or args['is_sale_rule'] is None:
            raise HPropParamError(_("is_sale_rule is required"))
        if 'name' not in args or not args['name']:
            raise HPropParamError(_("Name is required"))

        try:
            prop.shop_id = shop_id
            prop.is_sale_rule = args['is_sale_rule']
            prop.name = args['name']
            db.session.commit()
            # 修改value
            db.session.query(MProdAttrValue).filter(MProdAttrValue.prop_id==prop_id).delete()
            for i in args['prop_values']:
                prop_value = MProdAttrValue(
                    prop_id = prop_id, # type:ignore
                    val = i, # type:ignore
                    created_by = account.id,  # type:ignore
                )
                db.session.add(prop_value)
            db.session.commit()
            return prop
        except Exception as e:
            db.session.rollback()
            raise InternalServerError(str(e))
        

    @staticmethod
    def delete_prop(account:AccountWrap,prop_id):
        try:
            prop = db.session.get(MProdProperty,prop_id)
            if not prop:
                raise HPropNotFoundError(prop_id)
            db.session.delete(prop)
            db.session.query(MProdAttrValue).filter(MProdAttrValue.prop_id==prop_id).delete()
            db.session.commit()
        except HPropNotFoundError as e:
            raise e
        except Exception as e:
            db.session.rollback()
            raise InternalServerError(str(e))
        
    @staticmethod
    def get_prop_values(prop_id: str)->list[MProdAttrValue]:
        return db.session.query(MProdAttrValue).filter(MProdAttrValue.prop_id == prop_id).all()

    @staticmethod
    def get_prop_list(shop_id,is_sale_rule,page,page_size)->dict:
        try:
            query = db.session.query(MProdProperty).filter(MProdProperty.shop_id==shop_id)
            if is_sale_rule is not None:
                query = query.filter(MProdProperty.is_sale_rule==is_sale_rule)
            total = query.count()
            has_more = False
            if page and page_size and page >0 and page_size >0:
                query = query.offset((page-1)*page_size).limit(page_size)
                has_more = total > page*page_size
            data = query.all()
            return {"total":total,"has_more":has_more,"data":data}
        except Exception as e:
            logging.error(e)
            return {"total":0,"has_more":False,"data":[],"message":str(e)}